<?php
namespace app\index\controller;

use app\common\model\AttachMain;
use app\common\model\Debug;
use app\common\model\WebSiteCookie;
use OSS\OssClient;
use think\facade\App;
use think\facade\Request;

class Api
{

    public function __construct()
    {
        global $_G;
        set_time_limit(0);
        ignore_user_abort(true);
        $ip = trim(str_replace(['http://', 'https://'], '', $_G['setting']['api_domain']), '/');
        if (Request::ip() !== $ip) {
            exit('error');
        }
    }

    public function cookie()
    {
        $cookie = WebSiteCookie::where('cookie_id', '=', Request::param('cookie_id/d'))->find();
        if (!empty($cookie)) {
            $use_time = Request::param('use_time/s');
            if (!is_null($use_time)) {
                $cookie->use_time = $use_time;
            }
            $cookie->available = Request::param('available/d');
            $cookie->save();
        }
    }

    public function download()
    {
        global $_G;
        $attach = AttachMain::where('status', '=', 0)->find();
        if (empty($attach) || empty($_G['setting']['auto_save_type'])) {
            return 'attach is empty';
        }

        $attach->status = 1;
        $attach->save();
        $debug = new Debug;
        $debug->remark('begin');

        $savename    = '';
        $cookie_file = App::getConfigPath() . '/site_cookie/cookie_' . $attach->attach_id;

        $write_stream = fopen($attach->local_file, 'w');
        try {
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_TIMEOUT, 3600);
            curl_setopt($curl, CURLOPT_URL, $attach->response_url);
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36');
            curl_setopt($curl, CURLOPT_HTTPHEADER, [
                'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3',
                'Accept-Encoding: gzip, deflate',
                'Accept-Language: zh-CN,zh;q=0.9',
                'Cache-Control: max-age=0',
                'Connection: keep-alive',
                'Upgrade-Insecure-Requests: 1',
            ]);
            curl_setopt($curl, CURLOPT_ENCODING, 'gzip');
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            if (is_file($cookie_file)) {
                curl_setopt($curl, CURLOPT_COOKIEJAR, $cookie_file);
                curl_setopt($curl, CURLOPT_COOKIEFILE, $cookie_file);
            }
            curl_setopt($curl, CURLOPT_WRITEFUNCTION, function ($curl, $data) use ($write_stream, $attach, &$savename) {

                $code = curl_getinfo($curl, CURLINFO_HTTP_CODE);
                if (intval($code) / 100 != 2) {
                    return strlen($data);
                }

                $length        = strlen($data);
                $written_total = 0;
                $written_last  = 0;

                while ($written_total < $length) {
                    $written_last = fwrite($write_stream, substr($data, $written_total));

                    if ($written_last === false) {
                        return $written_total;
                    }

                    $written_total += $written_last;
                }

                if (empty($savename)) {
                    $bin      = substr($data, 0, 2);
                    $strInfo  = @unpack('C2chars', $bin);
                    $typeCode = intval($strInfo['chars1'] . $strInfo['chars2']);
                    $typeList = [
                        7790   => 'exe',
                        7784   => 'midi',
                        8297   => 'rar',
                        255216 => 'jpg',
                        7173   => 'gif',
                        6677   => 'bmp',
                        13780  => 'png',
                        8075   => 'zip',
                        4949   => 'tar',
                        55122  => '7z',
                        5666   => 'psd',
                    ];
                    $savename = $attach->attach_id . '.' . (empty($typeList[$typeCode]) ? $typeCode : $typeList[$typeCode]);
                }
                return $written_total;
            });
            $result = curl_exec($curl);
            $info   = curl_getinfo($curl);
            curl_close($curl);

        } catch (\Exception $e) {
            fclose($write_stream);
            if (is_file($attach->local_file)) {
                unlink($attach->local_file);
            }
            $attach->queue_error = $e->getMessage();
            $attach->save();
            return 'download error';
        }
        fclose($write_stream);
        if ($info['http_code'] == 200) {

            $debug->remark('end');
            if (is_file($attach->local_file)) {
                if (empty($attach->savename) && !empty($savename)) {
                    $attach->savename = $savename;
                }
                if (empty($attach->filename) && !empty($savename)) {
                    $attach->filename = $savename;
                }
                $attach->filesize      = filesize($attach->local_file);
                $attach->download_time = $debug->getRangeTime('begin', 'end');
                $attach->status        = 2;
                $attach->save();
            }
        }

        return 'download success';
    }

    public function upload()
    {
        global $_G;
        if (!$_G['setting']['AccessKeyId'] || !$_G['setting']['AccessKeySecret'] || !$_G['setting']['Endpoint'] || !$_G['setting']['Bucket'] || !in_array($_G['setting']['auto_save_type'], ['oss', 'local_oss'])) {
            return 'setting error';
        }
        $attach = AttachMain::where('status', '=', 2)->find();
        if (empty($attach) || (!is_file($attach->savename) && !is_file($attach->local_file))) {
            return 'attach is empty';
        }

        $attach->status = 3;
        $attach->save();
        $debug = new Debug;
        $debug->remark('begin');

        try {
            $ossClient = new OssClient($_G['setting']['AccessKeyId'], $_G['setting']['AccessKeySecret'], $_G['setting']['Endpoint']);
            if (is_file($attach->local_file)) {
                $ossClient->uploadFile($_G['setting']['Bucket'], $attach['savename'], $attach->local_file);
            } else if (is_file($attach->savename)) {
                $ossClient->uploadFile($_G['setting']['Bucket'], $attach['savename'], $attach->savename);
            }
        } catch (OssException $e) {
            $error = $e->getMessage();
        }
        $debug->remark('end');
        if (!empty($error)) {
            $attach->queue_error = $error;
            $attach->save();
            return 'upload error';
        }
        if (is_file($attach->local_file) && $_G['setting']['auto_save_type'] == 'oss') {
            @unlink($attach->local_file);
            if (!is_file($attach->local_file)) {
                $attach->local_file = '';
            }
        }
        if (is_file($attach->savename) && $_G['setting']['auto_save_type'] == 'oss') {
            @unlink($attach->savename);
        }
        $attach->queue_error = '';
        $attach->upload_time = $debug->getRangeTime('begin', 'end');
        $attach->status      = 4;
        $attach->save();
        return 'upload success';
    }
}
